home *** CD-ROM | disk | FTP | other *** search
- /*
-
-
- Copyright (C) 1990 Texas Instruments Incorporated.
-
- Permission is granted to any individual or institution to use, copy, modify,
- and distribute this software, provided that this complete copyright and
- permission notice is maintained, intact, in all copies and supporting
- documentation.
-
- Texas Instruments Incorporated provides this software "as is" without
- express or implied warranty.
-
-
- *
- * Created: MJF 07/05/89 -- Initial design and implementation.
- * Changed: MJF 02/20/90 -- Added group name support.
- * Changed: MJF 03/01/91 -- Added throw code written by grahamd@otc.otca.oz.au
- *
- * The C++ exception handling defmacro
- *
- * To use, declare:
- * #pragma defmacro EXCEPTION "exception" exception_g format_msg err_msg
- * hprintf delimiter=)
- *
- * where: exception_g is the name of the global variable to use as a temporary,
- * format_msg is the name of the slot in the exception class, err_msg
- * is the name of the text package for error message strings, and
- * hprintf is the name of the function which returns a formatted string
- * from the heap.
- */
-
- /*
- * EXCEPTION is a cpp macro used to construct an Exception object.
- * EXCEPTION has the following argument options:
- *
- * EXCEPTION(excp_name [, group_names] [, format_string] [rest_args])
- *
- * where group_names := group_name [, group_names ]
- * rest_args := rest_arg | [, rest_arg]
- * rest_arg := format_arg | key_value_slot_arg
- * format_arg := name
- * key_value_slot_arg := name = value
- * format_string := "string"
- * group_name := SYM(name)
- * excp_name := name
- *
- * In general:
- *
- * EXCEPTION(excp_name, SYM(group_name1), SYM(group_name2), format_string,
- * key1=val1, arg1, key2=val2, arg2);
- *
- * would generate:
- *
- * (Exception_g = new excp_name(2, SYM(group_name1), SYM(group_name2)),
- * Exception_g->format_msg = hprintf(ERR_MSG(format_string),
- * val1, arg1, val2, arg2),
- * Exception_g->key1 = val1,
- * Exception_g->key2 = val2,
- * Exception_g);
- *
- * Note that the value of the key-val-slot-args and the non-key-val-slot-args
- * are all gathered as format args for the hprintf function. Also note that
- * the key-val-slot-args and the non-key-args are intermixed. It mainly
- * depends on the format_string requirements.
- *
- * More specific examples using EXCEPTION:
- *
- * (1) EXCEPTION with group_name, error type and format string.
- *
- * EXCEPTION(Error, Serios_Error, "Serious problem here.");
- *
- * would generate:
- *
- * (Exception_g = new Error(SYM(Serious_Error)),
- * Exception_g->format_msg = hprintf(ERR_MSG("Serious problem here.")),
- * Exception_g);
- *
- *
- * (2) EXCEPTION with error type, format string and mixture of slot arguments
- * and format arguments.
- *
- * Assume a defined error type, Bad_Argment_Error, with two slots, arg_name and
- * arg_value.
- *
- * Class Bad_Argument_Error : public Fatal {
- * public:
- * char* arg_name;
- * int arg_value;
- * Bad_Argment_Error();
- * }
- *
- * then...
- *
- * EXCEPTION(Bad_Argument_Error,
- * "Arg %s has value %d which is out of range for %s."
- * arg_name="foo", arg_value=x, vec1);
- *
- * would generate...
- *
- * (Exception_g = new Bad_Argument_Error(),
- * Exception_g->arg_name = "foo",
- * Exception_g->arg_value = x,
- * Exception_g->format_msg =
- * hprintf(ERR_MSG("Arg %s has value %d which is out of range for %s."),
- * "foo", x, vec1),
- * Exception_g);
- *
- * (3) EXCEPTION with error type, and slot arguments (but no format message).
- *
- * Assume a defined error type, Out_Of_Range, with two slots, value and vector.
- *
- * Class Out_of_Range : public Fatal {
- * public:
- * int value;
- * Generic vector;
- * Out_of_Range() {
- * format_msg = "Value of %d is out of range for Vector %s."
- * }
- * void report(ostream& os) {
- * os << this->message_prefix();
- * os << form(format_msg, value, vector);
- * }
- * };
- * then...
- *
- * EXCEPTION(Out_of_Range, value=n, vector=v1);
- *
- * would generate...
- *
- * (Exception_g = new Out_of_Range(),
- * Exception_g->value = n,
- * Exception_g->vector = v1,
- * Exception_g);
- *
- */
-
- #include "defmacio.h"
- #include "macro.h"
-
- #define MAXBUF 512
- #define MAXGROUP 32
-
- exception(argc, argv)
- int argc;
- char* argv[];
- {
- char* global_excp; /* Exception_g */
- char* format_msg; /* exception format message slot name */
- char* group_fcn; /* function which updates the group slot */
- char* err_pkg; /* text package name for error message strings */
- char* format_fcn; /* hprintf (heap print) function */
-
- char buffer[MAXBUF];
-
- char* macname; /* EXCEPTION is the macro name */
- char* excp_name; /* the name of the exception type */
- char* group_names[MAXGROUP];
- int group_count;
- Arg* argp = NULL; /* always points to first arg in macro */
- Arg* excp_args; /* EXCEPTION macro arg pointer */
- Arg* fs_args; /* pointer to format or slot arguments*/
-
- if(argc <= 3) {
- fprintf(stderr, "Not enough arguments to #pragma defmacro exception\n");
- return(1);
- }
- global_excp = argv[1];
- format_msg = argv[2];
- group_fcn = argv[3];
- err_pkg = argv[4];
- format_fcn = argv[5];
-
- copytoken(buffer); /* Grab the macro name */
- macname = savestring(buffer);
-
- /* Gather all EXCEPTION arguments */
- if((argp = macro_args(macname)) == &arg_error) {
- fprintf(stderr, ".\n");
- return(1);
- }
-
- /* EXCEPTION takes at least one argument */
- if((excp_args = argp) == NULL) {
- fprintf(stderr, "EXCEPTION: No arguments specified.");
- return(1);
- }
-
- /* first EXCEPTION argument should be name of exception type */
- excp_name = excp_args->name;
- /* call exception constructor */
- sprintf(buffer, "\n(%s = new %s()", global_excp, excp_name);
- puts(buffer);
-
- group_count = 0;
- /* the next EXCEPTION argument might be the optional group names */
- for(excp_args = excp_args->next;
- excp_args !=NULL && excp_args->name[0] != '"'
- && *excp_args->value == EOS && excp_args->value != NULL;
- excp_args = excp_args->next, group_count++) {
- group_names[group_count] = excp_args->name;
- }
-
- if (group_count == 1) {
- /* only one group name */
- /* output: global_excp->group_fcn(group_name) */
- sprintf(buffer, ",\n%s->%s(%s)", global_excp, group_fcn,
- group_names[--group_count]);
- puts(buffer);
- }
-
- if (group_count != 0) {
- /* more than one group name */
- /* output: global_excp->group_fcn(group_count, group_name[0], ...,
- ..., group_name[n-1]) */
- sprintf(buffer, ",\n%s->%s(%d",
- global_excp, group_fcn, group_count);
- puts(buffer);
- /* output all of the group names */
- while (group_count != 0) {
- sprintf(buffer, ", %s", group_names[--group_count]);
- puts(buffer);
- }
- puts(")"); /* closing paren on group_fcn */
- }
-
- /* the next EXCEPTION argument might be the optional format string */
- if ((excp_args != NULL) && (excp_args->name[0] == '"')) {
- puts(",\n");
- /* output: global_excp->format_msg = hprintf(err_msg(format_string) ... */
- sprintf(buffer, "%s->%s = %s(%s(%s)", global_excp, format_msg, format_fcn,
- err_pkg, excp_args->name);
- puts(buffer);
- /* output: format_arg1, format_arg2, ...) */
- excp_args = excp_args->next; /* skip format string */
- for(fs_args=excp_args; /* now output each format arg */
- fs_args != NULL;
- fs_args=fs_args->next) {
- puts(", ");
- if (*fs_args->value != EOS) /* check key=value arg */
- puts(fs_args->value);
- else puts(fs_args->name);
- }
- putchar(')'); /* closing paren for format function, hprintf */
- }
-
- /* the next EXCEPTION argument might be key-value slots */
- for(fs_args = excp_args; fs_args != NULL; fs_args=fs_args->next) {
- if (*fs_args->value != EOS) {
- /* output: global_excp->key = value, */
- puts(",\n");
- sprintf(buffer, "((%s*) %s)->%s = %s", excp_name, global_excp,
- fs_args->name, fs_args->value);
- puts(buffer);
- }
- }
-
-
- /* last output is the global exception name */
- sprintf(buffer, ",\n(%s*) %s)", excp_name, global_excp);
- puts(buffer);
-
- for(argp = argp; argp != NULL;) {
- Arg* old = argp;
- argp = argp->next;
- free(old->name);
- if (*old->value) free(old->value);
- free(old);
- }
- free(macname);
- return 0;
- }
-
- /*
- * Handle throw translation
- *
- * throw Exception(__LINE__,__FILE__,"error");
- *
- * expands to
- *
- * (new Exception(__LINE__,__FILE__,"error"), terminate());
- *
- */
-
- int throw (argc, argv)
- int argc;
- char** argv;
- {
- char buff[256];
- char* line;
- if (copytoken(buff) == NULL)
- return 1;
- puts("( new ");
- line = scan_token(";");
- puts(line);
- puts(", terminate() );");
- return 0;
- }
-
-